home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xpuzzles.3 / xpuzzles / xpuzzles-5.3.1 / xskewb / xmskewb.c < prev    next >
C/C++ Source or Header  |  1996-02-07  |  15KB  |  525 lines

  1. /*
  2. # MOTIF-BASED SKEWB
  3. #
  4. #  xmskewb.c
  5. #
  6. ###
  7. #
  8. #  Copyright (c) 1993 - 95    David Albert Bagley, bagleyd@hertz.njit.edu
  9. #
  10. #                   All Rights Reserved
  11. #
  12. #  Permission to use, copy, modify, and distribute this software and
  13. #  its documentation for any purpose and without fee is hereby granted,
  14. #  provided that the above copyright notice appear in all copies and
  15. #  that both that copyright notice and this permission notice appear in
  16. #  supporting documentation, and that the name of the author not be
  17. #  used in advertising or publicity pertaining to distribution of the
  18. #  software without specific, written prior permission.
  19. #
  20. #  This program is distributed in the hope that it will be "useful",
  21. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  23. #
  24. */
  25.  
  26. /*
  27.   Version 5: 95/10/06 Xt/Motif
  28.   Version 4: 94/05/30 Xt
  29.   Version 3: 93/10/03 Motif
  30.   Version 2: 92/01/22 XView
  31.   Version 1: 91/03/19 SunView
  32. */
  33.  
  34. #include <stdlib.h>
  35. #include <stdio.h>
  36. #ifdef VMS
  37. #include <unixlib.h>
  38. #define getlogin cuserid
  39. #else
  40. #ifndef apollo
  41. #include <unistd.h>
  42. #endif
  43. #endif
  44. #include <X11/Intrinsic.h>
  45. #include <X11/StringDefs.h>
  46. #include <X11/Shell.h>
  47. #include <X11/cursorfont.h>
  48. #include <Xm/PanedW.h>
  49. #include <Xm/RowColumn.h>
  50. #include <Xm/Label.h>
  51. #include <Xm/LabelG.h>
  52. #include <Xm/ToggleB.h>
  53. #include "Skewb.h"
  54. #include "Skewb2d.h"
  55. #include "Skewb3d.h"
  56. #include "skewb.xbm"
  57. #include "mouse-l.xbm"
  58. #include "mouse-r.xbm"
  59.  
  60. #ifndef SCOREFILE
  61. #define SCOREFILE "/usr/games/lib/mball.scores"
  62. #endif
  63.  
  64. /* The following is in SkewbP.h also */
  65. #define MAXFACES 6
  66.  
  67. #define MAXRECORD 32767
  68.  
  69. static void Initialize();
  70. static void CallbackSkewb();
  71.  
  72. static void PrintRecord();
  73. static int HandleSolved();
  74. static void ReadRecords();
  75. static void WriteRecords();
  76.  
  77. static void OrientToggle();
  78. static void PracticeToggle();
  79. static void motif_printf();
  80.  
  81. static Arg arg[4];
  82. static Widget moves, record, message, skewb2d, skewb3d,
  83.   orientSwitch, practiceSwitch;
  84. static int skewbRecord[2], movesDsp = 0;
  85. static char messageDsp[128] = "Welcome";
  86.  
  87. static void Usage()
  88. {
  89.   (void) fprintf(stderr, "usage: xmskewb\n");
  90.   (void) fprintf(stderr,
  91.     "\t[-geometry [{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]]\n");
  92.   (void) fprintf(stderr,
  93.     "\t[-display [{host}]:[{vs}]][-fg {color}] [-bg {color}]\n");
  94.   (void) fprintf(stderr,
  95.     "\t[-{border|bd} {color}] [-mono] [-[no]orient]\n");
  96.   (void) fprintf(stderr,
  97.     "\t-[no]practice] [-face{0|1|2|3|4|5} {color}]\n");
  98.   exit(1);
  99. }
  100.  
  101. static XrmOptionDescRec options[] = {
  102.   {"-fg",        "*skewb.Foreground",    XrmoptionSepArg,    NULL},
  103.   {"-bg",        "*Background",        XrmoptionSepArg,    NULL},
  104.   {"-foreground",    "*skewb.Foreground",    XrmoptionSepArg,    NULL},
  105.   {"-background",    "*Background",        XrmoptionSepArg,    NULL},
  106.   {"-border",        "*skewb.pieceBorder",    XrmoptionSepArg,    NULL},
  107.   {"-bd",        "*skewb.pieceBorder",    XrmoptionSepArg,    NULL},
  108.   {"-mono",        "*skewb.mono",        XrmoptionNoArg,        "TRUE"},
  109.   {"-orient",        "*skewb.orient",    XrmoptionNoArg,        "TRUE"},
  110.   {"-noorient",        "*skewb.orient",    XrmoptionNoArg,        "FALSE"},
  111.   {"-practice",        "*skewb.practice",    XrmoptionNoArg,        "TRUE"},
  112.   {"-nopractice",    "*skewb.practice",    XrmoptionNoArg,        "FALSE"},
  113.   {"-face0",        "*skewb.faceColor0",    XrmoptionSepArg,    NULL},
  114.   {"-face1",        "*skewb.faceColor1",    XrmoptionSepArg,    NULL},
  115.   {"-face2",        "*skewb.faceColor2",    XrmoptionSepArg,    NULL},
  116.   {"-face3",        "*skewb.faceColor3",    XrmoptionSepArg,    NULL},
  117.   {"-face4",        "*skewb.faceColor4",    XrmoptionSepArg,    NULL},
  118.   {"-face5",        "*skewb.faceColor5",    XrmoptionSepArg,    NULL},
  119. };
  120.  
  121. int main(argc, argv)
  122.   int argc;
  123.   char *argv[];
  124. {
  125.   Widget toplevel;
  126.   Widget panel, panel2, rowcol, rowcol2, rowcol3;
  127.   Pixmap mouseLeftCursor, mouseRightCursor;
  128.   Pixel fg, bg;
  129.  
  130.   toplevel = XtInitialize(argv[0], "Skewb",
  131.     options, XtNumber(options), &argc, argv);
  132.   if (argc != 1)
  133.     Usage();
  134.  
  135.   XtSetArg(arg[0], XtNiconPixmap,
  136.     XCreateBitmapFromData(XtDisplay(toplevel),
  137.       RootWindowOfScreen(XtScreen(toplevel)),
  138.       (char *) skewb_bits, skewb_width, skewb_height));
  139.   XtSetArg(arg[1], XmNkeyboardFocusPolicy, XmPOINTER); /* not XmEXPLICIT */
  140.   XtSetValues(toplevel, arg, 2);
  141.   panel = XtCreateManagedWidget("panel", xmPanedWindowWidgetClass, toplevel,
  142.     NULL, 0);
  143.   panel2 = XtVaCreateManagedWidget("panel2", xmPanedWindowWidgetClass, panel,
  144.     XmNseparatorOn, False,
  145.     XmNsashWidth, 1,
  146.     XmNsashHeight, 1,
  147.     NULL);
  148.  
  149.   rowcol = XtVaCreateManagedWidget("Rowcol", xmRowColumnWidgetClass, panel2,
  150.     XmNnumColumns, 2,
  151.     XmNorientation, XmHORIZONTAL,
  152.     XmNpacking, XmPACK_COLUMN,
  153.     NULL);
  154.   XtVaGetValues(rowcol, XmNforeground, &fg, XmNbackground, &bg, NULL);
  155.   mouseLeftCursor = XCreatePixmapFromBitmapData(XtDisplay(rowcol),
  156.     RootWindowOfScreen(XtScreen(rowcol)), mouse_left_bits,
  157.     mouse_left_width, mouse_left_height, fg, bg,
  158.     DefaultDepthOfScreen(XtScreen(rowcol)));
  159.   mouseRightCursor = XCreatePixmapFromBitmapData(XtDisplay(rowcol),
  160.     RootWindowOfScreen(XtScreen(rowcol)), mouse_right_bits,
  161.     mouse_right_width, mouse_right_height, fg, bg,
  162.     DefaultDepthOfScreen(XtScreen(rowcol)));
  163.   XtVaCreateManagedWidget("mouseLeftText", xmLabelGadgetClass, rowcol,
  164.     XtVaTypedArg, XmNlabelString, XmRString, "Moves", 5, NULL);
  165.   XtVaCreateManagedWidget("mouseLeft", xmLabelGadgetClass, rowcol,
  166.     XmNlabelType, XmPIXMAP, XmNlabelPixmap, mouseLeftCursor, NULL);
  167.   XtVaCreateManagedWidget("mouseRightText", xmLabelGadgetClass, rowcol,
  168.     XtVaTypedArg, XmNlabelString, XmRString, "Randomize", 10, NULL);
  169.   XtVaCreateManagedWidget("mouseRight", xmLabelGadgetClass, rowcol,
  170.     XmNlabelType, XmPIXMAP, XmNlabelPixmap, mouseRightCursor, NULL);
  171.   XtVaCreateManagedWidget("movesText", xmLabelGadgetClass, rowcol,
  172.     XtVaTypedArg, XmNlabelString, XmRString, "Moves", 6, NULL);
  173.   moves = XtVaCreateManagedWidget("0", xmLabelWidgetClass, rowcol, NULL);
  174.   XtVaCreateManagedWidget("recordText", xmLabelGadgetClass, rowcol,
  175.     XtVaTypedArg, XmNlabelString, XmRString, "Record", 7, NULL);
  176.   record = XtVaCreateManagedWidget("0", xmLabelWidgetClass, rowcol, NULL);
  177.  
  178.   rowcol2 = XtVaCreateManagedWidget("Rowcol2", xmRowColumnWidgetClass, panel2,
  179.     XmNnumColumns, 1,
  180.     XmNorientation, XmHORIZONTAL,
  181.     XmNpacking, XmPACK_COLUMN,
  182.     NULL);
  183.   orientSwitch = XtVaCreateManagedWidget ("Orient",
  184.     xmToggleButtonWidgetClass, rowcol2,
  185.     NULL);
  186.   XtAddCallback(orientSwitch, XmNvalueChangedCallback, OrientToggle, NULL);
  187.   practiceSwitch = XtVaCreateManagedWidget ("Practice",
  188.     xmToggleButtonWidgetClass, rowcol2,
  189.     NULL);
  190.   XtAddCallback(practiceSwitch, XmNvalueChangedCallback, PracticeToggle, NULL);
  191.   rowcol3 = XtVaCreateManagedWidget("Rowcol3", xmRowColumnWidgetClass, panel2,
  192.     NULL);
  193.   message = XtVaCreateManagedWidget("Play Skewb! (use mouse and keypad)",
  194.     xmLabelWidgetClass, rowcol3,
  195.     NULL);
  196.  
  197.   skewb2d = XtCreateManagedWidget("skewb", skewb2dWidgetClass, panel,
  198.     NULL, 0);
  199.   XtVaSetValues(skewb2d,
  200.     XtNheight, 200,
  201.     NULL);
  202.   XtAddCallback(skewb2d, XtNselectCallback, CallbackSkewb, NULL);
  203.   skewb3d = XtCreateManagedWidget("skewb", skewb3dWidgetClass, panel,
  204.     NULL, 0);
  205.   XtVaSetValues(skewb3d,
  206.     XtNheight, 200,
  207.     NULL);
  208.   XtAddCallback(skewb3d, XtNselectCallback, CallbackSkewb, NULL);
  209.   Initialize();
  210.   XtRealizeWidget(toplevel);
  211.   XGrabButton(XtDisplay(skewb2d), AnyButton, AnyModifier, XtWindow(skewb2d),
  212.     TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
  213.     GrabModeAsync, GrabModeAsync, XtWindow(skewb2d),
  214.     XCreateFontCursor(XtDisplay(skewb2d), XC_crosshair));
  215.   XGrabButton(XtDisplay(skewb3d), AnyButton, AnyModifier, XtWindow(skewb3d),
  216.     TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
  217.     GrabModeAsync, GrabModeAsync, XtWindow(skewb3d),
  218.     XCreateFontCursor(XtDisplay(skewb3d), XC_crosshair));
  219.   XtMainLoop();
  220.  
  221. #ifdef VMS
  222.   return 1;
  223. #else
  224.   return 0;
  225. #endif
  226. }
  227.  
  228. /* There's probably a better way to assure that they are the same but
  229.    I don't know it off hand. */
  230. static void MakeEquivalent(orient, practice)
  231.   Boolean *orient, *practice;
  232. {
  233.   Boolean mono;
  234.   Pixel foreground, background, pieceBorder;
  235.   String faceColor[MAXFACES];
  236.  
  237.   XtVaGetValues(skewb2d,
  238.     XtNorient, orient,
  239.     XtNpractice, practice,
  240.     XtNmono, &mono,
  241.     XtNforeground, &foreground,
  242.     XtNbackground, &background,
  243.     XtNpieceBorder, &pieceBorder,
  244.     XtNfaceColor0, &(faceColor[0]),
  245.     XtNfaceColor1, &(faceColor[1]),
  246.     XtNfaceColor2, &(faceColor[2]),
  247.     XtNfaceColor3, &(faceColor[3]),
  248.     XtNfaceColor4, &(faceColor[4]),
  249.     XtNfaceColor5, &(faceColor[5]),
  250.     NULL);
  251.   XtVaSetValues(skewb2d,
  252.     XtNdirection, SKEWB_IGNORE,
  253.     XtNstart, FALSE,
  254.     NULL);
  255.   XtVaSetValues(skewb3d,
  256.     XtNorient, *orient,
  257.     XtNpractice, *practice,
  258.     XtNmono, mono,
  259.     XtNdirection, SKEWB_IGNORE,
  260.     XtNstart, FALSE,
  261.     XtNforeground, foreground,
  262.     XtNbackground, background,
  263.     XtNpieceBorder, pieceBorder,
  264.     XtNfaceColor0, faceColor[0],
  265.     XtNfaceColor1, faceColor[1],
  266.     XtNfaceColor2, faceColor[2],
  267.     XtNfaceColor3, faceColor[3],
  268.     XtNfaceColor4, faceColor[4],
  269.     XtNfaceColor5, faceColor[5],
  270.     NULL);
  271. }
  272.  
  273. static void Initialize()
  274. {
  275.   Boolean orient, practice;
  276.  
  277.   MakeEquivalent(&orient, &practice);
  278.   XmToggleButtonSetState(orientSwitch, orient, True);
  279.   XmToggleButtonSetState(practiceSwitch, practice, True);
  280.   ReadRecords();
  281.   PrintRecord(orient, practice);
  282. }
  283.  
  284. static void CallbackSkewb(w, clientData, callData)
  285.   Widget w;
  286.   caddr_t clientData;
  287.   skewbCallbackStruct *callData;
  288. {
  289.   Boolean orient, practice, start;
  290.   Widget otherw;
  291.  
  292.   if (w == skewb2d)
  293.     otherw = skewb3d;
  294.   else /* (w == skewb3d) */
  295.     otherw = skewb2d;
  296.   XtVaGetValues(w,
  297.     XtNorient, &orient,
  298.     XtNpractice, &practice,
  299.     XtNstart, &start,
  300.     NULL);
  301.   (void) strcpy(messageDsp, "");
  302.   switch (callData->reason) {
  303.     case SKEWB_RESTORE:
  304.       XtSetArg(arg[0], XtNdirection, SKEWB_RESTORE);
  305.       XtSetValues(otherw, arg, 1);
  306.       XtSetValues(w, arg, 1);
  307.       movesDsp = 0;
  308.       break;
  309.     case SKEWB_RESET:
  310.       movesDsp = 0;
  311.       break;
  312.     case SKEWB_ILLEGAL:
  313.       if (practice || start)
  314.         (void) strcpy(messageDsp, "Illegal move");
  315.       else
  316.         (void) strcpy(messageDsp, "Randomize to start");
  317.       break;
  318.     case SKEWB_MOVED:
  319.       movesDsp++;
  320.       XtSetArg(arg[0], XtNstart, TRUE);
  321.       XtSetArg(arg[1], XtNface, callData->face);
  322.       XtSetArg(arg[2], XtNpos, callData->position);
  323.       XtSetArg(arg[3], XtNdirection, callData->direction);
  324.       XtSetValues(otherw, arg, 4);
  325.       XtSetValues(w, arg, 1);
  326.       break;
  327.     case SKEWB_CONTROL:
  328.       XtSetArg(arg[0], XtNface, callData->face);
  329.       XtSetArg(arg[1], XtNpos, callData->position);
  330.       XtSetArg(arg[2], XtNdirection, callData->direction);
  331.       XtSetValues(otherw, arg, 3);
  332.       return;
  333.     case SKEWB_SOLVED:
  334.       if (practice)
  335.         movesDsp = 0;
  336.       else { 
  337.         if (HandleSolved(movesDsp, orient))
  338.           (void) sprintf(messageDsp, "Congratulations %s!!", getlogin());
  339.         else
  340.           (void) strcpy(messageDsp, "Solved!");
  341.       }
  342.       XtSetArg(arg[0], XtNstart, FALSE);
  343.       XtSetValues(w, arg, 1);
  344.       XtSetValues(otherw, arg, 1);
  345.       break;
  346.     case SKEWB_PRACTICE:
  347.       movesDsp = 0;
  348.       practice = !practice;
  349.       if (!practice)
  350.         (void) strcpy(messageDsp, "Randomize to start");
  351.       PrintRecord(orient, practice);
  352.       XtSetArg(arg[0], XtNpractice, practice);
  353.       XtSetArg(arg[1], XtNstart, FALSE);
  354.       XtSetValues(w, arg, 2);
  355.       XtSetValues(otherw, arg, 2);
  356.       XmToggleButtonSetState(practiceSwitch, practice, True);
  357.       break;
  358.     case SKEWB_RANDOMIZE:
  359.       movesDsp = 0;
  360.       XtSetArg(arg[0], XtNpractice, FALSE);
  361.       XtSetArg(arg[1], XtNstart, FALSE);
  362.       XtSetValues(w, arg, 2);
  363.       XtSetValues(otherw, arg, 2);
  364.       break; 
  365.     case SKEWB_ORIENT:
  366.       movesDsp = 0;
  367.       orient = !orient;
  368.       PrintRecord(orient, practice);
  369.       XtSetArg(arg[0], XtNorient, orient);
  370.       XtSetValues(w, arg, 1);
  371.       XtSetValues(otherw, arg, 1);
  372.       XmToggleButtonSetState(orientSwitch, orient, True);
  373.       break;
  374.     case SKEWB_COMPUTED:
  375.       XtSetArg(arg[0], XtNstart, FALSE);
  376.       XtSetValues(w, arg, 1);
  377.       XtSetValues(otherw, arg, 1);
  378.       break;
  379.     case SKEWB_UNDO:
  380.       movesDsp--;
  381.       XtSetArg(arg[0], XtNstart, TRUE);
  382.       XtSetArg(arg[1], XtNface, callData->face);
  383.       XtSetArg(arg[2], XtNpos, callData->position);
  384.       XtSetArg(arg[3], XtNdirection, callData->direction);
  385.       XtSetValues(otherw, arg, 4);
  386.       XtSetValues(w, arg, 1);
  387.       break;
  388.   }
  389.   motif_printf(message, "%s", messageDsp);
  390.   motif_printf(moves, "%d", movesDsp);
  391. }
  392.  
  393. static void OrientToggle(w, clientData, cbs)
  394.   Widget w;
  395.   XtPointer clientData;
  396.   XmToggleButtonCallbackStruct *cbs;
  397. {
  398.   Boolean orient = cbs->set, practice;
  399.  
  400.   XtVaGetValues(skewb2d,
  401.     XtNpractice, &practice,
  402.     NULL);
  403.   XtVaSetValues(skewb2d,
  404.     XtNorient, orient,
  405.     NULL);
  406.   XtVaSetValues(skewb3d,
  407.     XtNorient, orient,
  408.     NULL);
  409.   movesDsp = 0;
  410.   motif_printf(moves, "%d", movesDsp);
  411.   PrintRecord(orient, practice);
  412. }
  413.  
  414. static void PracticeToggle(w, clientData, cbs)
  415.   Widget w;
  416.   XtPointer clientData;
  417.   XmToggleButtonCallbackStruct *cbs;
  418. {
  419.   Boolean orient, practice = cbs->set;
  420.  
  421.   XtVaSetValues(skewb2d,
  422.     XtNpractice, practice,
  423.     XtNstart, FALSE,
  424.     NULL);
  425.   XtVaSetValues(skewb3d,
  426.     XtNpractice, practice,
  427.     XtNstart, FALSE,
  428.     NULL);
  429.   XtVaGetValues(skewb2d,
  430.     XtNpractice, &orient,
  431.     NULL);
  432.   movesDsp = 0;
  433.   motif_printf(moves, "%d", movesDsp);
  434.   if (!practice)
  435.     (void) strcpy(messageDsp, "Randomize to start");
  436.   PrintRecord(orient, practice);
  437. }
  438.  
  439. static void PrintRecord(orient, practice)
  440.   Boolean orient, practice;
  441. {
  442.   int i = (orient) ? 1 : 0;
  443.  
  444.   if (practice)
  445.     motif_printf(record, "practice");
  446.   else
  447.   if (skewbRecord[i] >= MAXRECORD)
  448.     motif_printf(record, "NEVER");
  449.   else
  450.     motif_printf(record, "%d", skewbRecord[i]);
  451. }
  452.  
  453. static int HandleSolved(counter, orient)
  454.   int counter;
  455.   Boolean orient;
  456. {
  457.   int i = (orient) ? 1 : 0;
  458.  
  459.   if (counter < skewbRecord[i]) {
  460.     skewbRecord[i] = counter;
  461.     if (orient && (skewbRecord[i] < skewbRecord[!i]))
  462.       skewbRecord[!i] = counter;
  463.     WriteRecords();
  464.     PrintRecord(orient, FALSE);
  465.     return TRUE;
  466.   }
  467.   return FALSE;
  468. }
  469.  
  470. static void ReadRecords()
  471. {
  472.   FILE *fp;
  473.   int n, orient;
  474.  
  475.   for (orient = 0; orient < 2; orient++)
  476.     skewbRecord[orient] = MAXRECORD;
  477.   if ((fp = fopen(SCOREFILE, "r")) == NULL)
  478.     motif_printf(message, "Can not open %s, taking defaults.", SCOREFILE);
  479.   else {
  480.     for (orient = 0; orient < 2; orient++) {
  481.       (void) fscanf(fp, "%d", &n);
  482.       skewbRecord[orient] = n;
  483.     }
  484.     (void) fclose(fp);
  485.   }
  486. }
  487.  
  488. static void WriteRecords()
  489. {
  490.   FILE *fp;
  491.   int orient;
  492.  
  493.   if ((fp = fopen(SCOREFILE, "w")) == NULL)
  494.     motif_printf(message, "Can not write to %s.", SCOREFILE);
  495.   else {
  496.     for (orient = 0; orient < 2; orient++)
  497.       (void) fprintf(fp, "%d ", skewbRecord[orient]);
  498.     (void) fprintf(fp, "\n");
  499.     (void) fclose(fp);
  500.   }
  501. }
  502.  
  503. #include <varargs.h>
  504. static void motif_printf(va_alist)
  505.   va_dcl
  506. {
  507.   Widget w;
  508.   char *format;
  509.   va_list args;
  510.   char str[1000];
  511.   Arg wargs[10];
  512.   XmString xmstr;
  513.  
  514.   va_start(args);
  515.   w = va_arg(args, Widget);
  516.   if (!XtIsSubclass(w, xmLabelWidgetClass))
  517.     XtError("motif_printf() requires a Label Widget");
  518.   format = va_arg(args, char *);
  519.   (void) vsprintf(str, format, args);
  520.   xmstr = XmStringCreateLtoR(str, XmSTRING_DEFAULT_CHARSET);
  521.   XtSetArg(wargs[0], XmNlabelString, xmstr);
  522.   XtSetValues(w, wargs, 1);
  523.   va_end(args);
  524. }
  525.